#include "viml/vm.h"
#include "viml/compiler.h"
#include <gtest/gtest.h>

namespace viml {

class VMTest : public ::testing::Test {
protected:
    VM vm_;
    Compiler compiler_;
    
    void SetUp() override {
        // 可以在这里添加测试所需的设置代码
    }
    
    void TearDown() override {
        // 可以在这里添加测试所需的清理代码
    }
};

TEST_F(VMTest, BasicExecution) {
    // 测试基本执行功能
    std::string source = "let x = 42";
    auto result = compiler_.compile(source);
    
    ASSERT_TRUE(result.success);
    EXPECT_TRUE(result.errors.empty());
    
    auto exec_result = vm_.execute(result.function);
    EXPECT_EQ(exec_result, ErrorCode::SUCCESS);
}

TEST_F(VMTest, ArithmeticOperations) {
    // 测试算术运算执行
    std::string source = "let x = 1 + 2 * 3";
    auto result = compiler_.compile(source);
    
    ASSERT_TRUE(result.success);
    EXPECT_TRUE(result.errors.empty());
    
    auto exec_result = vm_.execute(result.function);
    EXPECT_EQ(exec_result, ErrorCode::SUCCESS);
    
    // 验证计算结果
    auto value = vm_.get_local("x");
    EXPECT_TRUE(value.is_number());
    EXPECT_EQ(value.as_number(), 7.0); // 1 + (2 * 3) = 7
}

TEST_F(VMTest, FunctionCall) {
    // 测试函数调用执行
    std::string source = "function test() { return 42; }\nlet x = test()";
    auto result = compiler_.compile(source);
    
    ASSERT_TRUE(result.success);
    EXPECT_TRUE(result.errors.empty());
    
    auto exec_result = vm_.execute(result.function);
    EXPECT_EQ(exec_result, ErrorCode::SUCCESS);
    
    // 验证函数返回值
    auto value = vm_.get_local("x");
    EXPECT_TRUE(value.is_number());
    EXPECT_EQ(value.as_number(), 42.0);
}

TEST_F(VMTest, LoopExecution) {
    // 测试循环执行
    std::string source = "let sum = 0\nfor (let i = 0; i < 3; i = i + 1) {\n  sum = sum + i\n}";
    auto result = compiler_.compile(source);
    
    ASSERT_TRUE(result.success);
    EXPECT_TRUE(result.errors.empty());
    
    auto exec_result = vm_.execute(result.function);
    EXPECT_EQ(exec_result, ErrorCode::SUCCESS);
    
    // 验证循环结果 (0 + 0 + 1 + 2 = 3)
    auto value = vm_.get_local("sum");
    EXPECT_TRUE(value.is_number());
    EXPECT_EQ(value.as_number(), 3.0);
}

} // namespace viml